package qc.module.ehs.service;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.CollectionUtils;
import com.baomidou.mybatisplus.core.toolkit.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import qc.common.core.enums.EhsHazardPreventTypeEnum;
import qc.common.core.enums.TimeRangeLengthEnum;
import qc.common.core.exception.QCPromptException;
import qc.common.core.unify.QCUnifyReturnValue;
import qc.common.core.utils.DateUtil;
import qc.common.core.utils.IdentifierUtil;
import qc.module.ehs.dto.hazard.*;
import qc.module.ehs.entity.EhsHazardBasic;
import qc.module.ehs.entity.EhsHazardPreventrecord;
import qc.module.ehs.mapper.EhsHazardBasicMapper;
import qc.module.ehs.repository.EhsHazardBasicRepository;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;

/**
 * 危险源基本信息Service
 *
 * @author QuCheng Tech
 * @create 2024/6/13
 */
@Service
public class EhsHazardBasicService {
    
    @Autowired
    private EhsHazardBasicRepository repository;
    
    @Autowired
    EhsHazardPreventrecordService hazardPreventrecordService;

    //时间范围类型；默认按月
    private final Integer TIME_RANGE = TimeRangeLengthEnum.MONTH.getIndex();

    /**
     * 获取指定危险源基础信息
     *
     * @param id 危险源ID
     * @return EhsHazardBasicDto
     * @author QuCheng Tech
     * @since 2024/7/3
     */
    public EhsHazardBasicDto getHazardBasicInfo(String id) throws QCPromptException {
        if (StringUtils.isBlank(id)) throw new QCPromptException("危险源ID不能为空");
        
        EhsHazardBasic en = repository.selectById(id);
        
        if (Objects.nonNull(en)){
            return EhsHazardBasicMapper.MAPPER.toDto(en);
        }
        return null;
    }

    /**
     * 批量获取指定危险源基础信息
     *
     * @param ids 危险源ID集合
     * @return EhsHazardBasicDto
     * @author QuCheng Tech
     * @since 2024/7/22
     */
    public List<EhsHazardBasicDto> getHazardBasicInfoList(List<String> ids) throws QCPromptException {
        if (CollectionUtils.isEmpty(ids)) throw new QCPromptException("危险源ID集合不能为空");
        
        List<EhsHazardBasic> ens = repository.selectBatchIds(ids);
        
        if (CollectionUtils.isNotEmpty(ens)) 
            return EhsHazardBasicMapper.MAPPER.toDtoList(ens);
        return null;
    }

    /**
     * 获取指定危险源完整信息
     *
     * @param condition 查询条件
     * @return EhsHazardFullInfoDto
     * @author QuCheng Tech
     * @since 2024/7/3
     */
    public EhsHazardFullInfoDto getFullInfo(EhsHazardFullInfoConditionDto condition) throws QCPromptException {
        if (StringUtils.isBlank(condition.getId())) throw new QCPromptException("危险源ID不能为空");

        //查询时间处理
        Date beginDate = null;
        Date endDate = null;
        if (org.apache.commons.lang3.StringUtils.isNotBlank(condition.getBegintm())) {
            try {
                beginDate = DateUtil.parseDate(condition.getBegintm());
            } catch (Exception e) {
                // 时间转换错误，抛出自定义异常
                throw new QCPromptException("查询条件中的开始日期转换错误");
            }
        }
        if (org.apache.commons.lang3.StringUtils.isNotBlank(condition.getEndtm())) {
            try {
                endDate = DateUtil.parseDate(condition.getEndtm());
            } catch (Exception e) {
                // 时间转换错误，抛出自定义异常
                throw new QCPromptException("查询条件中的截止日期转换错误");
            }
        }

        Date beginTime = beginDate;
        Date endTime = endDate;
        if (condition.getTmtype() == null) condition.setTmtype(TIME_RANGE);
        if (condition.getTmtype() == TimeRangeLengthEnum.MONTH.getIndex()){
            //按月
            beginTime = DateUtil.newDate(DateUtil.getYear(beginDate), DateUtil.getMonth(beginDate) - 1, 0x1);
            endTime = DateUtil.addDays(DateUtil.addMonths(endDate, 0x1), -1);
        }else if (condition.getTmtype() == TimeRangeLengthEnum.QUARTER.getIndex()){
            //按季度：根据开始时间处理为开始时间所在季度的第一天，根据结束时间处理为结束时间所在季度最后一天
            beginTime = DateUtil.newDate(DateUtil.getYear(beginDate), 0x0, 0x1);
            int beginTimeMonth = DateUtil.getMonth(beginDate);
            if (beginTimeMonth >= 10)
                beginTime = DateUtil.newDate(DateUtil.getYear(beginDate), 0x9, 0x1);
            else if (beginTimeMonth >= 7)
                beginTime = DateUtil.newDate(DateUtil.getYear(beginDate), 0x6, 0x1);
            else if (beginTimeMonth >= 4)
                beginTime = DateUtil.newDate(DateUtil.getYear(beginDate), 0x3, 0x1);

            //先计算结束时间所在季度的开始时间endtmbegin，再根据endtmbegin计算结束时间
            Date endtmbegin = DateUtil.newDate(DateUtil.getYear(endDate), 0x0, 0x1);
            int endTimeMonth = DateUtil.getMonth(endDate);
            if (endTimeMonth >= 10)
                endtmbegin = DateUtil.newDate(DateUtil.getYear(endDate), 0x9, 0x1);
            else if (endTimeMonth >= 7)
                endtmbegin = DateUtil.newDate(DateUtil.getYear(endDate), 0x6, 0x1);
            else if (endTimeMonth >= 4)
                endtmbegin = DateUtil.newDate(DateUtil.getYear(endDate), 0x3, 0x1);
            endTime = DateUtil.addDays(DateUtil.addMonths(endtmbegin, 0x3), -1);
        }else{
            //默认按月
            beginTime = DateUtil.newDate(DateUtil.getYear(beginDate), DateUtil.getMonth(beginDate) - 1, 0x1);
            endTime = DateUtil.addDays(DateUtil.addMonths(endDate, 0x1), -1);
        }
        
        //1.获取指定危险源基础信息
        EhsHazardBasic hazardBasic = repository.selectById(condition.getId());
        
        if (hazardBasic != null){
            EhsHazardFullInfoDto result = new EhsHazardFullInfoDto();
            EhsHazardBasicDto basicDto = EhsHazardBasicMapper.MAPPER.toDto(hazardBasic);
            HazardIdentificationDto identificationDto = new HazardIdentificationDto();
            HazardRiskEvaluationDto evaluationDto = new HazardRiskEvaluationDto();
            
            //2.获取指定危险源辨识记录
            List<String> hazardIds = new ArrayList<>();
            hazardIds.add(condition.getId());
            List<EhsHazardPreventrecord> identificationecords = hazardPreventrecordService
                    .getRecords(hazardIds, EhsHazardPreventTypeEnum.IDENTIFICATION.getIndex(),beginTime,endTime,condition.getTmtype());
            if (CollectionUtils.isNotEmpty(identificationecords)){
                for (EhsHazardPreventrecord preventRecord : identificationecords){
                    if (basicDto.getHazardid().equals(preventRecord.getHazardid())){
                        identificationDto.setHazardid(preventRecord.getHazardid());
                        identificationDto.setIsmajor(preventRecord.getConafterismajor());
                        identificationDto.setSubunitcode(basicDto.getUnitname());
                        identificationDto.setPosition(basicDto.getPosition());
                        identificationDto.setIsreport(basicDto.getIsreport());
                        identificationDto.setDescription(preventRecord.getDescription());
                        //identificationDto.setResult(preventRecord.getResultormethod());
                        identificationDto.setUndercontrol(preventRecord.getUndercontrol());
                        identificationDto.setUnsafefactor(preventRecord.getUnsafefactor());
                        identificationDto.setFinalresult(preventRecord.getConafterhazardcategory());
                        identificationDto.setTmbegin(DateUtil.getDateString(preventRecord.getTmbegin()));
                        identificationDto.setTmend(DateUtil.getDateString(preventRecord.getTmend()));
                        identificationDto.setTmstr(preventRecord.getTmstr());
                        identificationDto.setByuser(preventRecord.getConusername());
                        identificationDto.setInuser(preventRecord.getInuser());
                        identificationDto.setIntm(DateUtil.getDateTimeString(preventRecord.getIntm()));
                    }
                }
            }
            
            //3.获取指定危险源评价记录
            List<EhsHazardPreventrecord> evaluationRecords = hazardPreventrecordService
                    .getRecords(hazardIds, EhsHazardPreventTypeEnum.EVALUATION.getIndex(),beginTime,endTime, condition.getTmtype());
            if (CollectionUtils.isNotEmpty(evaluationRecords)){
                for (EhsHazardPreventrecord preventRecord : evaluationRecords){
                    evaluationDto.setHazardid(preventRecord.getHazardid());
                    evaluationDto.setMethod(preventRecord.getResultormethod());
                    evaluationDto.setRisklevel(preventRecord.getConafterrisklevel());
                    evaluationDto.setContent(preventRecord.getConinformation());
                    evaluationDto.setTmbegin(DateUtil.getDateMonthString(preventRecord.getTmbegin()));
                    evaluationDto.setTmend(DateUtil.getDateMonthString(preventRecord.getTmend()));
                    evaluationDto.setTmstr(preventRecord.getTmstr());
                    evaluationDto.setByuser(preventRecord.getConusername());
                    evaluationDto.setInuser(preventRecord.getInuser());
                    evaluationDto.setIntm(DateUtil.getDateTimeString(preventRecord.getIntm()));
                }
            }
            
            //4.设置结果对象并返回
            result.setBasic(basicDto);
            result.setIdentification(identificationDto);
            result.setEvaluation(evaluationDto);
            return result;
        }
        
        return null;
    }

    /**
     * 根据指定单元ID获取危险源基础信息
     * 
     * @param unitId 单元ID
     * @return List<EhsHazardBasicDto>
     * @throws QCPromptException
     * @author QuCheng Tech
     * @since 2024/7/1
     */
    public List<EhsHazardBasicDto> getByUnitId(String unitId) throws QCPromptException {
        if (StringUtils.isBlank(unitId)) throw new QCPromptException("单元ID不能为空");
        LambdaQueryWrapper<EhsHazardBasic> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EhsHazardBasic::getUnitcode,unitId);
        List<EhsHazardBasic> ens = repository.selectList(wrapper);
        
        if (ens != null && ens.size() > 0x0){
            return EhsHazardBasicMapper.MAPPER.toDtoList(ens);
        }
        return null;
    }

    /**
     * 根据单元ID集合获取危险源基础信息
     * @param unitIds 单元ID集合
     * @return List<EhsHazardBasicDto>
     * @throws QCPromptException
     * @author QuCheng Tech
     * @since 2024/7/17
     */
    public List<EhsHazardBasicDto> getByUnitIds(List<String> unitIds) throws QCPromptException {
        if (CollectionUtils.isEmpty(unitIds)) throw new QCPromptException("单元ID集合不能为空");
        LambdaQueryWrapper<EhsHazardBasic> wrapper = new LambdaQueryWrapper<>();
        wrapper.in(EhsHazardBasic::getUnitcode,unitIds);
        List<EhsHazardBasic> ens = repository.selectList(wrapper);

        if (ens != null && ens.size() > 0x0){
            return EhsHazardBasicMapper.MAPPER.toDtoList(ens);
        }
        return null;
    }

    /**
     * 新增危险源基础信息
     * 
     * @param dto 新增对象
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/6/28
     */
    public String addHazardBasic(EhsHazardBasicDto dto){
        if (dto == null) return QCUnifyReturnValue.Warn("新增对象不能为空");
        if (StringUtils.isBlank(dto.getHazardname())) return QCUnifyReturnValue.Warn("危险源名称不能为空");
        if (StringUtils.isBlank(dto.getUnitcode())) return QCUnifyReturnValue.Warn("所属单元ID不能为空");
        if (StringUtils.isBlank(dto.getOrgcode())) return QCUnifyReturnValue.Warn("所属组织代码不能为空");
        
        //dto转entity
        EhsHazardBasic en = EhsHazardBasicMapper.MAPPER.toEntity(dto);
        
        if (StringUtils.isBlank(dto.getHazardid())) en.setHazardid(IdentifierUtil.randomUUID());
        
        if (repository.insert(en) < 0x1){
            return QCUnifyReturnValue.Warn("保存失败");
        }
        return QCUnifyReturnValue.Success();
    }

    /**
     * 修改危险源基础信息
     *
     * @param dto 修改对象
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/7/5
     */
    public String updateHazardBasic(EhsHazardBasicDto dto){
        if (dto == null) return QCUnifyReturnValue.Warn("对象不能为空");
        if (StringUtils.isBlank(dto.getHazardname())) return QCUnifyReturnValue.Warn("危险源名称不能为空");
        if (StringUtils.isBlank(dto.getUnitcode())) return QCUnifyReturnValue.Warn("所属单元ID不能为空");
        if (StringUtils.isBlank(dto.getOrgcode())) return QCUnifyReturnValue.Warn("所属组织代码不能为空");

        //dto转entity
        EhsHazardBasic en = EhsHazardBasicMapper.MAPPER.toEntity(dto);

        if (StringUtils.isBlank(dto.getHazardid())) en.setHazardid(IdentifierUtil.randomUUID());

        repository.updateById(en);
        return QCUnifyReturnValue.Success();
    }

    /**
     * 批量删除危险源基础信息
     *
     * @param hazardIds 危险源ID集合
     * @return 成功返回null，失败返回错误或提示信息
     * @author QuCheng Tech
     * @since 2024/7/1
     */
    public String batchDeleteHazardBasic(List<String> hazardIds){
        repository.deleteBatchIds(hazardIds);
        return QCUnifyReturnValue.Success();
    }

    /**
     * 获取指定单元指定类别、项目危险源基础信息
     * 
     * @param unitId 单元ID
     * @param hazardName 危险源名称
     * @param categoryName 类别名称
     * @param projectName 项目名称
     * @return EhsHazardBasicDto
     */
    public EhsHazardBasicDto getHazard(String unitId,String hazardName,String categoryName,String projectName){
        LambdaQueryWrapper<EhsHazardBasic> wrapper = new LambdaQueryWrapper<>();
        wrapper.eq(EhsHazardBasic::getUnitcode,unitId);
        wrapper.eq(EhsHazardBasic::getCategoryname,categoryName);
        wrapper.eq(EhsHazardBasic::getProjectname,projectName);
        wrapper.eq(EhsHazardBasic::getHazardname,hazardName);
        
        EhsHazardBasic en = repository.selectOne(wrapper);
        if (Objects.nonNull(en)){
            return EhsHazardBasicMapper.MAPPER.toDto(en);
        }
        return null;
    }
}
